package jxtcpserver

import (
	"bufio"
	"context"
	"encoding/binary"
	"fmt"
	"net"
	"sync"
	"time"

	"gitee.com/frankwangli/jxlog"
)

var serverlog = jxlog.NewLogger("./logs")

type Server struct {
	listener  net.Listener //侦听对象
	Pool      *Pool
	onMessage func(m *Message)
	locker    sync.Mutex
}

func (s *Server) NewConnection(c net.Conn) {
	//添加一个新的链接，先读取设备码
	//读取固定4字节的uint32 ID
	w := bufio.NewWriter(c)
	r := bufio.NewReader(c)
	var id uint32
	if err := binary.Read(r, binary.BigEndian, &id); err != nil {
		serverlog.Error("接收ID超时或失败:", err) // 超时或格式错误直接关闭连接
		return
	}
	var sid string
	sbuffer := make([]byte, 36)
	if _, err := r.Read(sbuffer); err != nil {
		serverlog.Error("读取链接Id错误:", err) // 超时或格式错误直接关闭连接
		return
	}
	sid = string(sbuffer)
	//取消读超时，转为长连接模式
	c.SetReadDeadline(time.Time{}) // [[8]]
	cid := sid
	fmt.Println("创建新的客户端链接", id, cid)
	ctx, cancel := context.WithCancel(context.Background())
	client := &Client{
		Id:        cid,
		MachineId: id,
		Conn:      c,
		onClose: func(err error) {
			s.locker.Lock()
			defer s.locker.Unlock()
			if err != nil {
				serverlog.Error("链接[", id, "]关闭，发生错误[", err.Error(), "]")
			}
			s.Pool.Del(id, cid)
		},
		ctx:       ctx,
		cancel:    cancel,
		onMessage: s.onMessage,
		writer:    w,
		reader:    r,
	}
	s.Pool.Set(id, cid, client)
	client.Run()
}
func NewServer(address string, f func(m *Message)) (*Server, error) {
	l, err := net.Listen("tcp", address)
	if err != nil {
		return nil, err
	}
	s := &Server{
		listener: l,
		Pool: &Pool{
			pool: make(map[uint32]*PoolClient),
		},
		onMessage: f,
	}
	go func() {
		for {
			conn, err := l.Accept()
			if err != nil {
				serverlog.Error("创建Tcp链接错误:", err.Error())
				continue
			}
			go s.NewConnection(conn)
		}
	}()
	return s, nil
}
func (s *Server) SendMessage(m *Message) (err error) {
	return s.Pool.SendMessage(m)
}
